package com.example;

import javax.activation.DataHandler;
// import java.io.IOException;
// import java.security.MessageDigest;
// import java.security.NoSuchAlgorithmException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.util.ByteArrayDataSource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.*;

import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PropertySourceFactory;
import org.springframework.stereotype.Component;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;

import javax.activation.DataHandler;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.util.ByteArrayDataSource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * Hello world!
 */
@Configuration
@ComponentScan // 扫描当前包下的组件（EmailSender）
class SpringConfig {
    // 配置YAML解析器，让Spring能读取application.yml
    @Bean
    public static PropertySourceFactory yamlPropertySourceFactory() {
        return (name, resource) -> {
            YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
            factory.setResources(resource.getResource());
            Properties properties = factory.getObject();
            return new PropertiesPropertySource(resource.getResource().getFilename(), properties);
        };
    }
}

@Component
public class EmailSender {

    @Autowired
    private Environment env; // 由Spring注入的环境变量

    // 从Environment读取配置（在main中通过Spring容器获取实例后调用）

    @Value("${smtp.host:默认值}")
    private String smtpHostByValue;

    public void initConfig() {

        String byEnv = env.getProperty("smtp.host", "Environment默认值");
        String byValue = this.smtpHostByValue;
        System.out.println("通过Environment读取：" + byEnv);
        System.out.println("通过@Value读取：" + byValue);
        System.out.println("通过yml读取：" + YamlConfigReader.getValue("smtp.host", ""));
        // 从application.yml读取配置
        smtpHost = YamlConfigReader.getValue("smtp.host", "");
        smtpFrom = YamlConfigReader.getValue("smtp.from", "");
        smtpUsername = YamlConfigReader.getValue("smtp.username", "");
        smtpPassword = YamlConfigReader.getValue("smtp.password", "");
        smtpAuth = YamlConfigReader.getValue("smtp.auth", "off");
        smtpPort = Integer.parseInt(YamlConfigReader.getValue("smtp.port", "25"));
        smtpSsl = Boolean.parseBoolean(YamlConfigReader.getValue("smtp.ssl", "false"));
        attachmentPath = YamlConfigReader.getValue("email.attachment-path", "");

        // 打印配置（验证是否读取成功）
        System.out.println("读取到的配置：");
        System.out.println("SMTP主机：" + smtpHost);
        System.out.println("发件人：" + smtpFrom);
        System.out.println("端口：" + smtpPort);
    }

    /**
     * Says hello to the world.
     * 
     * @param args The arguments of the program.
     */
    public static void main(String[] args) {
        // 加载application.yml配置
        try {

            // 手动设置配置（实际使用中会由Spring注入）
            // 关键：在main中手动启动Spring容器，加载配置并注入依赖
            ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);

            // 从Spring容器中获取EmailSender实例（此时env已被注入）
            EmailSender sender = context.getBean(EmailSender.class);

            // 调用方法读取配置（通过env）
            sender.initConfig();

            // 准备邮件信息
            List<String> toList = Arrays.asList("daixiaoyong@df-nissanfc.com");
            List<String> ccList = Arrays.asList("daixiaoyong@df-nissanfc.com");
            String subject = "测试邮件";
            String content = "<h1>这是一封测试邮件</h1><p>邮件内容测试</p>";
            List<String> fileList = Arrays.asList("test.txt"); // 附件文件名

            // 发送邮件
            Map<String, Object> result = sender.sendEmail(toList, ccList, subject, content, fileList);
            System.out.println("发送结果: " + result);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 封装Environment获取属性的方法
    private String getEnvProperty(String key, String defaultValue) {
        return env.getProperty(key, defaultValue);
    }

    // 从application.yml读取配置
    @Value("${smtp.host:}")
    private String smtpHost;

    @Value("${smtp.from:}")
    private String smtpFrom;

    @Value("${smtp.username:}")
    private String smtpUsername;

    @Value("${smtp.password:}")
    private String smtpPassword;

    @Value("${smtp.auth:off}")
    private String smtpAuth;

    @Value("${smtp.port:25}")
    private int smtpPort;

    @Value("${smtp.ssl:false}")
    private boolean smtpSsl;

    @Value("${email.attachment-path:}")
    private String attachmentPath;

    /**
     * 发送邮件
     * 
     * @param toList   收件人列表
     * @param ccList   抄送列表
     * @param subject  邮件主题
     * @param content  邮件内容
     * @param fileList 附件文件名列表
     * @return 发送结果
     */
    public Map<String, Object> sendEmail(List<String> toList, List<String> ccList,
            String subject, String content, List<String> fileList) {
        Map<String, Object> resultMap = new HashMap<>();

        try {
            // 验证必要配置
            if (isEmpty(smtpHost) || isEmpty(smtpFrom) || isEmpty(smtpUsername)) {
                resultMap.put("success", false);
                resultMap.put("message", "邮件服务器配置不完整");
                return resultMap;
            }

            // 配置邮件属性
            Properties props = new Properties();
            props.put("mail.smtp.host", smtpHost);
            props.put("mail.smtp.port", smtpPort);
            props.put("mail.smtp.auth", "on".equals(smtpAuth) ? "true" : "false");
            props.put("mail.debug", "false");
            props.put("mail.smtp.timeout", 30000);
            props.put("mail.smtp.connectiontimeout", 10000);
            props.put("mail.smtp.writetimeout", 30000);
            props.put("mail.transport.protocol", "smtp");

            // 如果需要SSL加密
            if (smtpSsl) {
                props.put("mail.smtp.ssl.enable", "true");
                props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
                props.put("mail.smtp.socketFactory.fallback", "false");
            }

            // 创建会话
            Session session = Session.getInstance(props, new Authenticator() {
                @Override
                protected PasswordAuthentication getPasswordAuthentication() {
                    return new PasswordAuthentication(smtpUsername, smtpPassword);
                }
            });

            // 创建邮件消息
            MimeMessage message = new MimeMessage(session);
            message.setFrom(new InternetAddress(smtpFrom));

            // 设置收件人
            if (toList != null && !toList.isEmpty()) {
                InternetAddress[] toAddresses = new InternetAddress[toList.size()];
                for (int i = 0; i < toList.size(); i++) {
                    toAddresses[i] = new InternetAddress(toList.get(i));
                }
                message.setRecipients(Message.RecipientType.TO, toAddresses);
            } else {
                resultMap.put("success", false);
                resultMap.put("message", "收件人列表不能为空");
                return resultMap;
            }

            // 设置抄送
            if (ccList != null && !ccList.isEmpty()) {
                InternetAddress[] ccAddresses = new InternetAddress[ccList.size()];
                for (int i = 0; i < ccList.size(); i++) {
                    ccAddresses[i] = new InternetAddress(ccList.get(i));
                }
                message.setRecipients(Message.RecipientType.CC, ccAddresses);
            }

            // 设置主题和发送时间
            //message.setSubject(subject, "UTF-8");
            message.setSubject(subject );
            message.setSentDate(new Date());

            // 创建多部分消息
            Multipart multipart = new MimeMultipart();

            // 添加邮件内容
            MimeBodyPart contentPart = new MimeBodyPart();
            //contentPart.setContent(content, "text/html;charset=UTF-8");
            contentPart.setText( content );
            
            multipart.addBodyPart(contentPart);

            // 添加附件
            if (fileList != null && !fileList.isEmpty()) {
                for (String fileName : fileList) {
                    MimeBodyPart attachmentPart = new MimeBodyPart();

                    // 构建完整的附件路径
                    String fullPath = isEmpty(attachmentPath) ? fileName : attachmentPath + File.separator + fileName;
                    File file = new File(fullPath);

                    if (file.exists() && file.isFile()) {
                        try (InputStream is = new FileInputStream(file)) {
                            ByteArrayDataSource dataSource = new ByteArrayDataSource(is, "application/octet-stream");
                            attachmentPart.setDataHandler(new DataHandler(dataSource));
                            //attachmentPart.setFileName(new String(fileName.getBytes(StandardCharsets.UTF_8), "ISO-8859-1"));
                            attachmentPart.setFileName(fileName);
                            multipart.addBodyPart(attachmentPart);
                        }
                    } else {
                        resultMap.put("warning", "附件不存在或无法访问: " + fullPath);
                    }
                }
            }

            // 设置邮件内容
            message.setContent(multipart);

            // 发送邮件
            Transport.send(message);

            resultMap.put("success", true);
            resultMap.put("message", "邮件发送成功");
            resultMap.put("timestamp", new Date());

        } catch (MessagingException e) {
            resultMap.put("success", false);
            resultMap.put("message", "邮件发送失败: " + e.getMessage());
            resultMap.put("exception", e);
        } catch (IOException e) {
            resultMap.put("success", false);
            resultMap.put("message", "处理附件时出错: " + e.getMessage());
            resultMap.put("exception", e);
        } catch (Exception e) {
            resultMap.put("success", false);
            resultMap.put("message", "发生未知错误: " + e.getMessage());
            resultMap.put("exception", e);
        }

        return resultMap;
    }

    /**
     * 判断字符串是否为空
     */
    private boolean isEmpty(String str) {
        return str == null || str.trim().isEmpty();
    }

    /**
     * 测试发送邮件
     */

}
